package com.flycms.modules.site.service.impl;

import com.flycms.common.pager.Pager;
import com.flycms.common.utils.mark.SnowFlakeUtils;
import com.flycms.common.utils.result.Result;
import com.flycms.modules.site.dao.SiteColumnDao;
import com.flycms.modules.site.entity.SiteColumn;
import com.flycms.modules.site.entity.SiteColumnListVO;
import com.flycms.modules.site.entity.SiteColumnTree;
import com.flycms.modules.site.entity.SiteColumnVO;
import com.flycms.modules.site.service.SiteColumnService;
import com.flycms.modules.system.entity.SystemModule;
import com.flycms.modules.system.service.SystemModuleService;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;


@Service
public class SiteColumnServiceImpl implements SiteColumnService {
    @Autowired
    private SiteColumnDao siteColumnDao;

    @Autowired
    private SystemModuleService systemModuleService;

    private List<SiteColumn> childMenu=new CopyOnWriteArrayList<>();

    private List<Long> fatherChild = new CopyOnWriteArrayList<>();

    // ///////////////////////////////
    // /////       增加       ////////
    // ///////////////////////////////

    /**
     * 用户添加企业网站分类
     *
     * @param siteColumn
     * @return
     */
    @Transactional
    public Object addUserSiteColumn(SiteColumn siteColumn){
        if (this.checkSiteColumnByTitle(null,siteColumn.getSiteId(),siteColumn.getParentId(),siteColumn.getColumnTitle())){
            return Result.failure("当前统计目录下分类名");
        }
        siteColumn.setId(SnowFlakeUtils.nextId());
        siteColumn.setCreateTime(LocalDateTime.now());
        siteColumnDao.save(siteColumn);
        return Result.success();
    }
    // ///////////////////////////////
    // /////        刪除      ////////
    // ///////////////////////////////

    // ///////////////////////////////
    // /////        修改      ////////
    // ///////////////////////////////
    /**
     * 用户编辑企业网站分类
     *
     * @param siteColumn
     * @return
     */
    @Transactional
    public Object editUserSiteColumn(SiteColumn siteColumn){
        if (this.checkSiteColumnByTitle(siteColumn.getId(),siteColumn.getSiteId(),siteColumn.getParentId(),siteColumn.getColumnTitle())){
            return Result.failure("当前统计目录下分类名已存在");
        }
        siteColumn.setUpdateTime(LocalDateTime.now());
        siteColumnDao.update(siteColumn);
        return Result.success();
    }


    // ///////////////////////////////
    // /////        查詢      ////////
    // ///////////////////////////////

    /**
     * 查询网站id和相同父级下是否有重复分类名称
     * @param id
     *         是否排除该条信息id，比如修改当前信息时要排除当前标题
     * @param siteId
     *         网站id
     * @param parentId
     *         父级id
     * @param columnTitle
     *         分类名称
     * @return
     */
    public boolean checkSiteColumnByTitle(Long id,Long siteId, Long parentId, String columnTitle) {
        int totalCount = siteColumnDao.checkSiteColumnByTitle(id,siteId,parentId,columnTitle);
        return totalCount > 0 ? true : false;
    }

    /**
     * 按id查询分类信息
     *
     * @param id
     * @return
     */
    public SiteColumn findById(Long id){
        return siteColumnDao.findById(id);
    }

    /**
     * 按分类id加网站id查询分类信息
     *
     * @param id
     *         分类id
     * @param siteId
     *         网站id
     * @return
     */
    public SiteColumn findByIdAndSiteId(Long id,Long siteId){
        return siteColumnDao.findByIdAndSiteId(id,siteId);
    }

    /**
     * 按分类id加网站id查询父级分类名
     *
     * @param id
     *         分类id
     * @param siteId
     *         网站id
     * @return
     */
    public String parentName(Long id,Long siteId){
        SiteColumn column=siteColumnDao.findByIdAndSiteId(id,siteId);
        if(column!=null){
            return column.getColumnTitle();
        }
        return "顶级分类";
    }

    /**
     * 按网站id查询分类树
     *
     * @param siteId
     * @return
     */
    public List<SiteColumnTree> findColumnTreeBySiteId(Long siteId){
        List<SiteColumn> olumnList=siteColumnDao.findBySiteId(siteId);
        List<SiteColumnTree> treelist = this.getColumnTree(olumnList, 0l,null);
        return treelist;
    }

    /**
     * 按网站id查询和分类树，传递模型id判断设置状态
     *
     * @param siteId
     * @param channel
     * @return
     */
    public List<SiteColumnTree> findColumnTreeBySiteId(Long siteId,Long channel){
        List<SiteColumn> olumnList=siteColumnDao.findBySiteId(siteId);
        List<SiteColumnTree> treelist = this.getColumnTree(olumnList, 0l,channel);
        return treelist;
    }

    /**
     * 按网站ID和分类父级id查询分类列表
     *
     * @return
     */
    public List<SiteColumn> selectColumnListByParentId(Long siteId,Long parentId) {
        StringBuffer whereStr = new StringBuffer();
        whereStr.append(" status = 1");
        whereStr.append(" and deleted = 0");
        if (!StringUtils.isEmpty(parentId)) {
            whereStr.append(" and parent_id = #{entity.parentId}");
        }else{
            whereStr.append(" and parent_id =0");
        }
        whereStr.append(" and site_id = #{entity.siteId}");
        Pager<SiteColumn> pager = new Pager();
        //排序设置
        pager.addOrderProperty("sort_order", false,true);
        //使用limit进行查询翻页
        pager.addLimitProperty(false);
        //查询条件
        SiteColumn entity = new SiteColumn();
        entity.setParentId(parentId);
        entity.setSiteId(siteId);
        pager.setEntity(entity);
        pager.setWhereStr(whereStr.toString());
        List<SiteColumn> sitelsit = siteColumnDao.queryList(pager);
        return sitelsit;
    }

    /**
     * 按网站ID查询所有分类列表提供给前台网站树
     *
     * @return
     */
    public List<SiteColumnListVO> selectColumnListTreetable(Long siteId) {
        //javabean 映射工具
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        MapperFacade mapper = mapperFactory.getMapperFacade();

        StringBuffer whereStr = new StringBuffer();
        whereStr.append(" status = 1");
        whereStr.append(" and deleted = 0");
        whereStr.append(" and site_id = #{entity.siteId}");
        Pager<SiteColumn> pager = new Pager();
        //排序设置
        pager.addOrderProperty("sort_order", true,true);
        //使用limit进行查询翻页
        pager.addLimitProperty(false);
        //查询条件
        SiteColumn entity = new SiteColumn();
        entity.setSiteId(siteId);
        pager.setEntity(entity);
        pager.setWhereStr(whereStr.toString());
        List<SiteColumn> sitelsit = siteColumnDao.queryList(pager);
        return mapper.mapAsList(sitelsit,SiteColumnListVO.class);
    }

    /**
     * 按网站ID和分类父级id查询分类列表
     *
     * @return
     */
    public List<SiteColumnVO> selectColumnList(Long siteId,Integer row,Long parentId) {
        StringBuffer whereStr = new StringBuffer();
        whereStr.append(" status = 1");
        whereStr.append(" and deleted = 0");
        if (!StringUtils.isEmpty(parentId)) {
            whereStr.append(" and parent_id = #{entity.parentId}");
        }else{
            whereStr.append(" and parent_id =0");
        }
        whereStr.append(" and site_id = #{entity.siteId}");
        Pager<SiteColumn> pager = new Pager(0, row);
        //排序设置
        pager.addOrderProperty("sort_order", false,true);
        //使用limit进行查询翻页
        pager.addLimitProperty(true);
        //查询条件
        SiteColumn entity = new SiteColumn();
        entity.setParentId(parentId);
        entity.setSiteId(siteId);
        pager.setEntity(entity);
        pager.setWhereStr(whereStr.toString());
        List<SiteColumn> sitelsit = siteColumnDao.queryList(pager);
        List<SiteColumnVO> columnVOList = new ArrayList<>();
        sitelsit.forEach(column -> {
            SiteColumnVO columnVO= new SiteColumnVO();
            SystemModule module  = systemModuleService.findById(column.getChannel());
            columnVO.setId(column.getId());
            columnVO.setColumnTitle(column.getColumnTitle());
            if(module!=null){
                columnVO.setModuleShow(module.getModuleType());
            }
            columnVO.setColumnUrl(column.getColumnUrl());
            columnVO.setNewWindow(column.getNewWindow());
            columnVOList.add(columnVO);
        });
        return columnVOList;
    }

    /**
     * 将有子父级关系的list集合转出树形结构
     *
     * @param list
     * @param parentId
     * @return
     */
    public List<SiteColumnTree> getColumnTree(List<SiteColumn> list, Long parentId, Long channel){
        List<SiteColumnTree> result =  new ArrayList<SiteColumnTree>();
        List<SiteColumnTree> temp =  new ArrayList<SiteColumnTree>();
        for(SiteColumn entity : list){
            if(entity.getParentId().equals(parentId)){
                SiteColumnTree tree = new SiteColumnTree();
                tree.setId(entity.getId());
                tree.setName(entity.getColumnTitle());
                if(entity.getChannel().equals(channel)){
                    tree.setStatus(1);
                }else {
                    tree.setStatus(0);
                }
                SystemModule module  = systemModuleService.findById(entity.getChannel());
                if(module != null){
                    tree.setModuleType(module.getModuleType());
                }
                temp = getColumnTree(list,entity.getId(),channel);
                if(temp.size() > 0){
                    tree.setChildren(temp);
                }
                result.add(tree);
            }
        }
        return result;
    }

    /**
     * 获取某个父节点下面的所有子节点
     * @param menuList
     * @param parentId
     * @return
     */
    public List<SiteColumn> nodeAllList( List<SiteColumn> menuList, Long parentId){
        List<SiteColumn> result =  new CopyOnWriteArrayList<>();
        for(SiteColumn mu: menuList){
            //遍历出父id等于参数的id，add进子节点集合
            if(mu.getParentId().equals(parentId)){
                result.add(mu);
                //递归遍历下一级
                List<SiteColumn> nodeList = nodeAllList(menuList,mu.getId());
                result.addAll(nodeList);
            }
        }
        return result;
    }

    /**
     * 获取某个子节点下面的所有父节点
     * @param menuList
     * @param id
     * @return
     */
    public List<String> fatherAllList( List<SiteColumn> menuList, Long id){
        List<String> result =  new CopyOnWriteArrayList<>();
        for(SiteColumn mu: menuList){
            //遍历出父id等于参数的id，add进子节点集合
            if(mu.getId().equals(id)){
                result.add(mu.getId().toString());
                //递归遍历下一级
                List<String> nodeList = fatherAllList(menuList,mu.getParentId());
                result.addAll(nodeList);
            }
        }
        return result;
    }

    /**
     *
     * @param siteId
     *         网站id
     * @param id
     *         当前分类id
     * @return
     */
    public List<String> resultNodeList(Long siteId, Long id) {
        List<SiteColumn> columnList=siteColumnDao.findBySiteId(siteId);
        return this.fatherAllList(columnList,id);
    }

    /**
     * 按父级分类id查询是否属于当前分类id，并且当前id不能转移到自己id下任何分类内
     *
     * @param siteId
     *         网站id
     * @param id
     *         当前分类id
     * @param parentId
     *         父级分类id
     * @return
     */
    public Boolean checkColumnNode(Long siteId, Long id, Long parentId){
        if(parentId == 0){
            return true;
        }
        if(id.equals(parentId)){
            return false;
        }
        //按网站id查询当前网站所有分类
        List<SiteColumn> nodelist=siteColumnDao.findBySiteId(siteId);
        if(nodelist==null){
            return true;
        }
        List<SiteColumn> childList=this.nodeAllList(nodelist,id);
        if(childList==null){
            return true;
        }
        for(SiteColumn entity : childList){
            if (entity.getId().equals(parentId)){
                return false;
            }
        }
        return true;
    }
}
